package com.example.radixconversion.controller;

import cn.hutool.json.JSONObject;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author geekYang
 * @version 1.0
 * @since 1.0
 */
@RestController
@RequestMapping("/radix")
public class RadixConversionController {
    private static final String DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private List<JSONObject> logList = new ArrayList<>();

    @RequestMapping(value = "/convert", method = RequestMethod.POST)
    public JSONObject radixConversion(@RequestBody JSONObject jsonObject) {
        String number = (String) jsonObject.get("number");
        String fromRadix = (String) jsonObject.get("fromRadix");
        String toRadix = (String) jsonObject.get("toRadix");
        try {
            String convert = convert(number, fromRadix, toRadix);
            JSONObject result = new JSONObject().set("result", convert);
            //保存日志
            log(number, fromRadix, toRadix, convert, "转换成功");
            return result;
        } catch (Exception e) {
            log(number, fromRadix, toRadix, null, "转换失败");
        }
        //返回结果
        return new JSONObject().set("error", "数字不符合进制输入规范");
    }

    @RequestMapping(value = "/logByDateSort", method = RequestMethod.GET)
    public JSONObject logByDateSort() {
        List<JSONObject> logDesc = logList.stream()
                .sorted(Comparator.comparingLong(o -> o.getLong("mills", 0L)))
                .collect(Collectors.toList());
        return new JSONObject().set("log", logDesc);
    }

    /**
     * 将给定的字符串表示的数字从源进制转换为目标进制。
     *
     * @param numberStr 要转换的数字字符串表示形式。
     * @param fromRadix 源进制。
     * @param toRadix   目标进制。
     * @return 转换后的字符串表示形式。
     */
    public static String convert(String numberStr, String fromRadix, String toRadix) {
        if (fromRadix.equals(toRadix)) {
            return numberStr;
        }
        int fromInt = Integer.parseInt(fromRadix);
        int toInt = Integer.parseInt(toRadix);
        // 先转换为十进制
        long decimalValue = Long.parseLong(numberStr, fromInt);
        return toRadix != "10" ? convertFromDecimal(decimalValue, toInt) : Long.toString(decimalValue);
    }

    private static String convertFromDecimal(long decimal, int radix) {
        StringBuilder result = new StringBuilder();
        while (decimal > 0) {
            result.insert(0, DIGITS.charAt((int) (decimal % radix)));
            decimal /= radix;
        }
        return result.length() > 0 ? result.toString() : "0";
    }

    private void log(String number, String fromRadix, String toRadix, String convert, String isSuccess) {
        //日志对象
        JSONObject log = new JSONObject();
        Date date = new Date();
        long millis = System.currentTimeMillis();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formatDate = sdf.format(date);
        log.set("number", number);
        log.set("fromRadix", fromRadix);
        log.set("toRadix", toRadix);
        log.set("convert", convert);
        log.set("date", formatDate);
        log.set("millis", millis);
        log.set("isSuccess", isSuccess);
        logList.add(log);
    }


}
